package cn.com.cfae.iras.doc.analyze.parse.kv;

import cn.com.cfae.iras.doc.analyze.parse.GsonUtil;
import cn.com.cfae.iras.doc.analyze.parse.RegexUtil;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;

public class KVTableParser {

    private static Logger logger = LoggerFactory.getLogger(KVTableParser.class);
    private static String M1_SY_SPLITKEY = "指";
    String M5_FXR_SPLITKEY = ":";


    private RegexUtil regexUtil = new RegexUtil();

    /**
     * 发行人基本情况
     *
     * @param jsonElement
     * @return
     */
    public List<KVItem> parseKVTable2(JsonElement jsonElement) {
        List<KVText> kvTextList = new ArrayList<KVText>();
        JsonObject e1 = jsonElement.getAsJsonArray().get(0).getAsJsonObject();
        JsonArray dataArray = e1.get("data").getAsJsonArray();
        double pageWidth = e1.get("width").getAsDouble();
        double pageHeight = e1.get("height").getAsDouble();
        logger.info("pageWidth：{}，pageHeight：{}。", pageWidth, pageHeight);

        Set<Double> keyStartSet = new TreeSet<Double>((o1, o2) -> {
            return o1.compareTo(o2);
        });

        Set<Double> lineWidthSet = new TreeSet<Double>((o1, o2) -> {
            return o2.compareTo(o1);
        });

        int offset = 0;

        for (int i = 0; i < dataArray.size(); i++) {
            JsonArray items = dataArray.get(i).getAsJsonArray();
            JsonObject item = items.get(0).getAsJsonObject();
            double left = item.get("left").getAsDouble();
            double top = item.get("top").getAsDouble();
            double width = item.get("width").getAsDouble();
            double height = item.get("height").getAsDouble();
            String text = item.get("text").getAsString();
            if (StringUtils.isEmpty(text)) {
                continue;
            }
            logger.info("text:{}，top：{}，left：{}。", text, top, left);
            if (top == 0 && left == 0) {
                continue;
            }


            lineWidthSet.add(left + width);
            keyStartSet.add(left);
            KVText kvText = new KVText();
            TextLayout kvTextLayout = new TextLayout();
            kvText.add(kvTextLayout);
            kvText.setText(item.get("text").getAsString());
            if (regexUtil.isFXRJBXX(kvText.getText())) {
                offset = (i + 1);
            }
            kvTextLayout.setLeft(left);
            kvTextLayout.setTop(top);
            kvTextLayout.setWidth(item.get("width").getAsDouble());
            kvTextLayout.setHeight(item.get("height").getAsDouble());
            kvTextList.add(kvText);
            keyStartSet.add(kvText.getLeft());
        }

        logger.info("pdf共计：{}行。", kvTextList.size());

        /**
         * key左边起始位置
         */
        double keyStart = keyStartSet.toArray(new Double[]{})[0];

        Set<Double> valueStartSet = new TreeSet<Double>((o1, o2) -> {
            return o1.compareTo(o2);
        });

        /**
         * 行最大文本宽度
         */
        double maxLineWidth = lineWidthSet.toArray(new Double[]{})[0];


//        for (int i = 0; i < kvTextList.size(); i++) {
//            KVText kvText = kvTextList.get(i);
//            double left = kvText.getLeft();
//            if (left == keyStart) {
//                offset = i;
//                break;
//            }
//        }

        for (int i = offset; i < kvTextList.size(); i++) {
            KVText kvText = kvTextList.get(i);
            double left = kvText.getLeft();
            double width = kvText.getWidth();
            if (left > keyStart && !kvText.getText().contains(M5_FXR_SPLITKEY)) {
                valueStartSet.add(left);
            }
        }

        Set<Double> keyWidthSet = new TreeSet<Double>((o1, o2) -> {
            return o2.compareTo(o1);
        });
        double valueStart = valueStartSet.toArray(new Double[]{})[0];
        for (int i = offset; i < kvTextList.size(); i++) {
            KVText kvText = kvTextList.get(i);
            double left = kvText.getLeft();
            double width = kvText.getWidth();
            if (left >= keyStart && !kvText.getText().contains(M5_FXR_SPLITKEY) && (left + width) < valueStart) {
                keyWidthSet.add(width);
            }
        }

        logger.info("开始解析KV结构......");

        KVItem kvItem = null;

        KVText current = null;
        List<KVItem> kvItemList = new ArrayList<>();
        for (int i = offset; i < kvTextList.size(); i++) {
            current = kvTextList.get(i);
            logger.info("发行人基本信息：{}。", current.getText());
            if(regexUtil.isFXR_SPLIT_BY_COLON(current.getText())){
                kvItem=new KVItem();
                current.setKvType(KVType.KV);
                kvItem.addItem(current);
                kvItemList.add(kvItem);
            }
        }

        for (int i = 0; i < kvItemList.size(); i++) {
            KVItem kvItem1 = kvItemList.get(i);
            logger.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>");
            for (KVText kvText : kvItem1.getKevItemList()) {
                logger.info(kvText.getText());
            }
            logger.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>");
        }
        logger.info("解析KV结构完成。");
        return kvItemList;
    }


    /**
     * 名词释义
     *
     * @param jsonElement
     * @return
     */
    public List<KVItem> parseKVTable(JsonElement jsonElement) {
        List<KVText> kvTextList = new ArrayList<KVText>();
        JsonObject e1 = jsonElement.getAsJsonArray().get(0).getAsJsonObject();
        JsonArray dataArray = e1.get("data").getAsJsonArray();
        double pageWidth = e1.get("width").getAsDouble();
        double pageHeight = e1.get("height").getAsDouble();
        logger.info("pageWidth：{}，pageHeight：{}。", pageWidth, pageHeight);

        Set<Double> keyStartSet = new TreeSet<Double>((o1, o2) -> {
            return o1.compareTo(o2);
        });

        Set<Double> lineWidthSet = new TreeSet<Double>((o1, o2) -> {
            return o2.compareTo(o1);
        });

        for (int i = 0; i < dataArray.size(); i++) {
            JsonArray items = dataArray.get(i).getAsJsonArray();
            JsonObject item = items.get(0).getAsJsonObject();
            double left = item.get("left").getAsDouble();
            double top = item.get("top").getAsDouble();
            double width = item.get("width").getAsDouble();
            double height = item.get("height").getAsDouble();
            String text = item.get("text").getAsString();
            if (StringUtils.isEmpty(text)) {
                continue;
            }
            logger.info("text:{}，top：{}，left：{}。", text, top, left);
            if (top == 0 && left == 0) {
                continue;
            }
            lineWidthSet.add(left + width);
            keyStartSet.add(left);
            KVText kvText = new KVText();
            TextLayout kvTextLayout = new TextLayout();
            kvText.add(kvTextLayout);
            kvText.setText(item.get("text").getAsString());
            kvTextLayout.setLeft(left);
            kvTextLayout.setTop(top);
            kvTextLayout.setWidth(item.get("width").getAsDouble());
            kvTextLayout.setHeight(item.get("height").getAsDouble());
            kvTextList.add(kvText);
            keyStartSet.add(kvText.getLeft());
        }

        logger.info("pdf共计：{}行。", kvTextList.size());

        /**
         * key左边起始位置
         */
        double keyStart = keyStartSet.toArray(new Double[]{})[0];

        Set<Double> valueStartSet = new TreeSet<Double>((o1, o2) -> {
            return o1.compareTo(o2);
        });


        /**
         * 行最大文本宽度
         */
        double maxLineWidth = lineWidthSet.toArray(new Double[]{})[0];

        int offset = -1;
        for (int i = 0; i < kvTextList.size(); i++) {
            KVText kvText = kvTextList.get(i);
            double left = kvText.getLeft();
            if (left == keyStart) {
                offset = i;
                break;
            }
        }

        for (int i = offset; i < kvTextList.size(); i++) {
            KVText kvText = kvTextList.get(i);
            double left = kvText.getLeft();
            double width = kvText.getWidth();
            if (left > keyStart && !kvText.getText().contains(M1_SY_SPLITKEY)) {
                valueStartSet.add(left);
            }
        }


        Set<Double> keyWidthSet = new TreeSet<Double>((o1, o2) -> {
            return o2.compareTo(o1);
        });
        double valueStart = valueStartSet.toArray(new Double[]{})[0];
        for (int i = offset; i < kvTextList.size(); i++) {
            KVText kvText = kvTextList.get(i);
            double left = kvText.getLeft();
            double width = kvText.getWidth();
            if (left >= keyStart && !kvText.getText().contains(M1_SY_SPLITKEY) && (left + width) < valueStart) {
                keyWidthSet.add(width);
            }
        }
        double maxKeyWidth = keyWidthSet.toArray(new Double[]{})[0];
        logger.info("keyStart：{}，maxKeyWidth：{}，valueStart：{}，文本最大宽度：{}，名词释义开始位置：{}。", keyStart, maxKeyWidth, valueStart, maxLineWidth, offset);
        logger.info("开始解析KV结构......");

        KVItem kvItem = null;
        KVText previous = null;
        KVText current = null;
        List<KVItem> kvItemList = new ArrayList<>();
        for (int i = offset; i < kvTextList.size(); i++) {
            previous = current;
            current = kvTextList.get(i);
            String text = current.getText();
            logger.info("第{}行，文本：{}。", i, current.getText());
            if (current.getLeft() >= valueStart && (current.getWidth() + current.getLeft()) <= maxLineWidth && !current.getText().contains(M1_SY_SPLITKEY)) {
                current.setKvType(KVType.V);
            } else if (current.getLeft() >= keyStart && current.getWidth() <= maxKeyWidth && !current.getText().contains(M1_SY_SPLITKEY)) {
                current.setKvType(KVType.K);
            } else if (current.getLeft() >= keyStart && current.getLeft() < valueStart && (current.getWidth() + current.getLeft()) <= maxLineWidth && !current.getText().contains(M1_SY_SPLITKEY)) {
                current.setKvType(KVType.KV);
            } else if (current.getLeft() >= keyStart && (current.getWidth() + current.getLeft()) <= maxLineWidth && current.getText().contains(M1_SY_SPLITKEY)) {
                current.setKvType(KVType.KV);
            } else if (current.getLeft() >= keyStart && (current.getWidth() + current.getLeft()) <= valueStart && current.getText().contains(M1_SY_SPLITKEY)) {
                current.setKvType(KVType.KV);
            }


            int lineWidth = Double.valueOf(current.getLeft() + current.getWidth()).intValue();
            int previousLineWidth = 0;
            if (previous != null) {
                previousLineWidth = Double.valueOf(previous.getLeft() + previous.getWidth()).intValue();
            }
            if (previous == null) {
                kvItem = new KVItem();
                kvItem.addItem(current);
                kvItemList.add(kvItem);
            } else if (previous.getKvType() == KVType.K) {
                if (current.getKvType() == KVType.K) {
                    if (current.getWidth() > previous.getWidth()) {
                        kvItem = new KVItem();
                        kvItem.addItem(current);
                        kvItemList.add(kvItem);
                    }
                } else if (current.getKvType() == KVType.KV) {
                    if (maxKeyWidth - previous.getWidth() > 1) {
                        kvItem = new KVItem();
                        kvItem.addItem(current);
                        kvItemList.add(kvItem);
                    }
                    if (previous.getWidth() - maxKeyWidth < 1 && previous.getWidth() - maxKeyWidth >= 0) {
                        kvItem.addItem(current);
                    }
                } else if (current.getKvType() == KVType.V) {
                    if (current.getWidth() > previous.getWidth() && current.getLeft() >= valueStart) {
                        kvItem = new KVItem();
                        kvItem.addItem(current);
                        kvItemList.add(kvItem);
                    }
                }
            } else if (previous.getKvType() == KVType.KV) {
                if (current.getKvType() == KVType.K) {
                    if (maxKeyWidth - current.getWidth() > 1) {
                        kvItem.addItem(current);
                    }
                } else if (current.getKvType() == KVType.KV) {
                    if (current.getLeft() > keyStart && (current.getLeft() + current.getWidth()) < valueStart) {
                        kvItem.addItem(current);
                        continue;
                    }
                    if (previousLineWidth < valueStart) {
                        if (maxLineWidth - lineWidth <= 1 && maxLineWidth - lineWidth >= 0) {
                            kvItem.addItem(current);
                        }
                        if (maxLineWidth - lineWidth > 1) {
                            kvItem.addItem(current);
                        }
                    } else {
                        if (lineWidth > previousLineWidth) {
                            kvItem = new KVItem();
                            kvItem.addItem(current);
                            kvItemList.add(kvItem);
                        }
                        if (lineWidth < previousLineWidth) {
                            if ((maxLineWidth - previousLineWidth) > 6) {
                                kvItem = new KVItem();
                                kvItem.addItem(current);
                                kvItemList.add(kvItem);
                            } else {
                                kvItem.addItem(current);
                            }
                        }
                    }
                } else if (current.getKvType() == KVType.V) {
                    if (previousLineWidth < valueStart) {
                        if (maxLineWidth - previousLineWidth > 9) {
                            kvItem.addItem(current);
                        }
                    } else {
                        if (lineWidth > previousLineWidth) {
                            kvItem = new KVItem();
                            kvItem.addItem(current);
                            kvItemList.add(kvItem);
                        } else {
                            kvItem.addItem(current);
                        }
                    }
                }
            } else if (previous.getKvType() == KVType.V) {
                if (current.getKvType() == KVType.K) {
                    if (current.getWidth() < maxKeyWidth) {
                        kvItem.addItem(current);
                    }
                } else if (current.getKvType() == KVType.KV) {
                    if (lineWidth < valueStart) {
                        kvItem.addItem(current);
                    } else {
                        if (maxLineWidth - previousLineWidth > 9) {
                            if (lineWidth > previousLineWidth) {
                                kvItem = new KVItem();
                                kvItem.addItem(current);
                                kvItemList.add(kvItem);
                            }
                        }

                        if (lineWidth - previousLineWidth <= 9 && lineWidth - previousLineWidth >= 0) {
                            kvItem.addItem(current);
                        }
                    }
                } else if (current.getKvType() == KVType.V) {
                    int textWidth = Double.valueOf(current.getWidth()).intValue();
                    int previousTextWidth = Double.valueOf(previous.getWidth()).intValue();
                    if (maxLineWidth - previousLineWidth > 9) {
                        if (current.getWidth() >= previous.getWidth()) {
                            kvItem = new KVItem();
                            kvItem.addItem(current);
                            kvItemList.add(kvItem);
                        }
                    } else {
                        if (textWidth >= previousTextWidth) {
                            kvItem.addItem(current);
                        }
                    }
                }
            }
        }

        for (int i = 0; i < kvItemList.size(); i++) {
            KVItem kvItem1 = kvItemList.get(i);
            logger.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>");
            for (KVText kvText : kvItem1.getKevItemList()) {
                logger.info(kvText.getText());
            }
            logger.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>");

        }
        logger.info("解析KV结构完成。");
        return kvItemList;
    }

    private void transfer(List<KVItem> kvItemList) {
        KVItem kvItem;

        for (int i = 0; i < kvItemList.size(); i++) {
            kvItem = kvItemList.get(i);
            KVText kvText = null;
            for (int j = 0; j < kvItem.getKevItemList().size(); j++) {
                kvText = kvItem.getKevItemList().get(j);

            }
        }
    }
}
